package com.zed.game.answer.fetures;

import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import com.zed.api.common.localstore.LocalStoreUtils;
import com.zed.api.games.answer.show.AnswerShowWorld;
import com.zed.api.persistence.core.util.PersistentException;
import com.zed.infrastructure.persistence.mybatis.plus.core.EntityAccessObject;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

import javax.sql.DataSource;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 基于JDBC的题库读写器
 *
 * @author Zed
 */
public class JdbcQuestionBankEntityAccessObject extends EntityAccessObject<AnswerShowWorldEntity> implements QuestionBankReadWriter {

    private Long size;

    public JdbcQuestionBankEntityAccessObject() {
        super(AnswerShowWorldBaseMapper.class);
        this.setDataSource(null);
    }

    @Override
    public void setDataSource(DataSource dataSource) {
        Path resolve = LocalStoreUtils.getInstance().getWorkingDirectory().resolve("data.db");
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:h2:file://".concat(resolve.toString()).concat(";IFEXISTS=TRUE"));
        config.setUsername("sa");
        config.setPassword("123");
        dataSource = new HikariDataSource(config);
        super.setDataSource(dataSource);
    }

    @Override
    protected void init() {
        super.init();
        DefaultResourceLoader loader = new DefaultResourceLoader();
        Resource resource = loader.getResource("question_bank_schema.sql");
        ResourceDatabasePopulator resourceDatabasePopulator = new ResourceDatabasePopulator();
        resourceDatabasePopulator.addScript(resource);
        DatabasePopulatorUtils.execute(resourceDatabasePopulator, this.getDataSource());
    }

    @Override
    public void save(AnswerShowWorld... answerShowWorlds) throws PersistentException {
        Collection<AnswerShowWorldEntity> saves = Arrays.stream(answerShowWorlds).map(AnswerShowWorldEntity::new).collect(Collectors.toList());
        if (this.saveBatch(saves)) {
            if (this.size != null) {
                this.size += saves.size();
            }
        }
    }

    @Override
    public void delete(String... ids) throws PersistentException {
        this.removeByIds(Arrays.stream(ids).toList());
    }

    @Override
    public List<AnswerShowWorld> loadWithHopeSize(long size) {
        if (this.size == null) {
            this.size = this.count();
        }

        if (size > this.size) {
            size = this.size;
        }

        AnswerShowWorldBaseMapper mapper = AnswerShowWorldBaseMapper.class.cast(this.getMapper());
        return mapper.getRandom(size)
                .stream()
                .map(AnswerShowWorldEntity::getAnswerShowWorld)
                .collect(Collectors.toList());
    }
}
